package com.zf.yaml_properties_ini;

import org.apache.commons.collections4.MapUtils;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;

import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Properties;

/**
 * .yaml/.yml 文件读写测试
 * <p>
 * 读取不会出现乱码问题，默认yaml是使用的Unicode编码，自动解析使用的是哪种unicode编码来读取数据。
 * 写入使用的 字符流 默认使用的是UTF-8；如果使用 字节流 写入String数据时的getBytes()方法也默认使用UTF-8,所以不会乱码
 */
public class YamlReadWriteTest {
    public static void main(String[] args) throws IOException {
        // 读取yaml
        // testRead();
        // 读取 包含多个文档的yaml, 文件之间用 “---”分隔
        testReadMultiDoc();

        // 导出yaml
        // testWrite();
        // 导出 包含多个文档的yaml, 文件之间用 “---”分隔
        // testWriteMultiDoc();
    }

    /**
     * 读取yaml
     */
    public static void testRead() throws IOException {
        Yaml yaml = new Yaml();
        ClassLoader classLoader = YamlReadWriteTest.class.getClassLoader();
        InputStream inputStream = classLoader.getResourceAsStream("yaml_one_doc_test.yaml");
        // 默认读取为 LinkedHashMap<String, Object>
        Map<String, Object> map = yaml.load(inputStream);
        inputStream.close();
        System.out.println(map);
        Map<String, Object> server = (Map<String, Object>) MapUtils.getMap(map, "server");
        Map<String, Object> database = (Map<String, Object>) MapUtils.getMap(map, "database");
        Map<String, Object> say = (Map<String, Object>) MapUtils.getMap(map, "say");
        System.out.println(server);
        System.out.println(database);
        System.out.println(say);


        InputStream inputStream2 = classLoader.getResourceAsStream("yaml_one_doc_test.yaml");
        // 读取为指定类型
        Properties properties = yaml.loadAs(inputStream2, Properties.class);
        inputStream2.close();
        System.out.println(properties);
        Map<String, Object> server2 = (Map<String, Object>) properties.get("server");
        Map<String, Object> database2 = (Map<String, Object>) properties.get("database");
        Map<String, Object> say2 = (Map<String, Object>) properties.get("say");
        System.out.println(server2);
        System.out.println(database2);
        System.out.println(say2);

    }

    /**
     * 读取 包含多个文档的yaml, 文件之间用 “---”分隔
     */
    public static void testReadMultiDoc() {
        Yaml yaml = new Yaml();
        // yaml.load读取包含多个文档的yaml时会报错，只能使用 yaml.loadAll 读取
        // Map<String, Object> map = yaml.load(YamlReadTest.class.getClassLoader().getResourceAsStream("yaml_multi_doc_test.yaml"));
        Iterable<Object> mapIter = yaml.loadAll(YamlReadWriteTest.class.getClassLoader().getResourceAsStream("yaml_multi_doc_test.yaml"));
        for (Object o : mapIter) {
            Map<String, Object> next = (Map<String, Object>) o;
            System.out.println(next);
        }

    }

    /**
     * 导出到yaml
     */
    public static void testWrite() throws IOException {
        // 设置导出的操作
        DumperOptions options = new DumperOptions();
        // 设置块格式
        /*
        流式格式：
            server: {host: localhost, port: 9999}
            database: {url: 'jdbc:mysql://localhost:3306/mydb', username: user, password: pass}
            say: {hello: 你 好, greeting: hello}
        块格式：
            server:
              host: localhost
              port: 9999
            database:
              url: jdbc:mysql://localhost:3306/mydb
              username: user
              password: pass
            say:
              hello: 你 好
              greeting: hello

         */
        options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
        Yaml yaml = new Yaml(options);

        Map<String, Object> map = new LinkedHashMap<>();

        Map<String, Object> server = new LinkedHashMap<>();
        server.put("host", "localhost");
        server.put("port", 9999);
        map.put("server", server);

        Map<String, Object> database = new LinkedHashMap<>();
        database.put("url", "jdbc:mysql://localhost:3306/mydb");
        database.put("username", "user");
        database.put("password", "pass");
        map.put("database", database);

        Map<String, Object> say = new LinkedHashMap<>();
        say.put("hello", "你 好");
        say.put("greeting", "hello");
        map.put("say", say);

        // 导出到文件
        FileWriter fileWriter = new FileWriter("D:\\test.yaml");
        yaml.dump(map, fileWriter);
        fileWriter.flush();
        fileWriter.close();

        // 导出文字符串
        String res = yaml.dump(map);
        System.out.println(res);
    }


    /**
     * 导出 包含多个文档的yaml, 文件之间用 “---”分隔
     */
    public static void testWriteMultiDoc() throws IOException {
        // 设置导出的操作
        DumperOptions options = new DumperOptions();
        // 设置块格式
        options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
        Yaml yaml = new Yaml(options);


        Map<String, Object> server = new LinkedHashMap<>();
        server.put("host", "localhost");
        server.put("port", 9999);

        Map<String, Object> database = new LinkedHashMap<>();
        database.put("url", "jdbc:mysql://localhost:3306/mydb");
        database.put("username", "user");
        database.put("password", "pass");

        Map<String, Object> say = new LinkedHashMap<>();
        say.put("hello", "你 好");
        say.put("greeting", "hello");

        // 导出到文件
        FileWriter fileWriter = new FileWriter("D:\\test_multi.yaml");
        yaml.dumpAll(Arrays.asList(server, database, say).iterator(), fileWriter);
        fileWriter.flush();
        fileWriter.close();

        // 导出到字符串
        String res = yaml.dumpAll(Arrays.asList(server, database, say).iterator());
        System.out.println(res);
    }
}
